﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Jzy.Workflow.Flow;
using Jzy.Workflow.Node;
using Jzy.Workflow.Form;
using Jzy.Workflow.Snap;
using Frame.Lib.Data;
using Frame.Lib.Core.Base;

namespace Jzy.Workflow.Task
{
    public class FlowTaskBO : CommonOperate<FlowTaskInfo>
    {
        private FlowTaskDAL _task;

        protected override BaseDAL DAL
        {
            get
            {
                return _task;
            }
        }

        private FlowFormBO _form;
        public FlowTaskBO()
        {
            _task = new FlowTaskDAL();
         
            _form = new FlowFormBO();           
        }

        public FlowTaskBO(DBHelper db)
        {
            _task = new FlowTaskDAL();
            _task.dbOper = db;

            _form = new FlowFormBO(db);
            base.dbOper = db;
        }


        public override FlowTaskInfo GetInfo(object id)
        {
            if (id == null)
            {
                return null;
            }
            FlowTaskInfo info = base.GetInfo(id);
            InitDelegate(info);
            return info;
        }


        public void InitDelegate(FlowTaskInfo info)
        {
            info.GetFlowInfo = flowID => (new FlowBO(base.dbOper)).GetInfo(flowID);
            info.GetNodeInfo = (nodeID,formID) => 
            {
                return GetNodeInfo(nodeID, formID);
            };
            info.GetFormInfo = formID => (new FlowFormBO(base.dbOper)).GetInfo(formID);
            info.GetTaskInfo = taskID => GetInfo(taskID);//taskID有可能为空
            info.GetNextTaskInfos = taskID => _task.GetNextTaskList(taskID);
        }

        private FlowNodeInfo GetNodeInfo(int nodeID, int formID)
        {
            FlowNodeInfo info = new FlowNodeInfo(_form.GetInfo(formID).SnapInfo, nodeID);
            return info;
        }

        /// <summary>
        /// 获得待办件列表
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<FlowTaskInfo> GetRequiredList(int userID)
        {
            List<FlowTaskInfo> list = _task.GetRequiredList(userID);
            BindFormInfo(list);

            //去掉暂停的
            list = list.Where(t => t.FormInfo.State != (int)FormState.暂停).ToList();

            return list;
        }

        /// <summary>
        /// 获得草稿箱列表
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<FlowTaskInfo> GetDraftList(int userID)
        {
            List<FlowTaskInfo> list = _task.GetDraftList(userID);
            BindFormInfo(list);
            return list;

        }

        /// <summary>
        /// 获得已办件列表
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public List<FlowTaskInfo> GetDealtList(int userID)
        {
            //暂未考虑对已归档的进行处理
            List<FlowTaskInfo> list = _task.GetDealtList(userID);
            BindFormInfo(list);
            return list;
        }

        /// <summary>
        /// 获得能够错发回收的列表
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        public IEnumerable<FlowTaskInfo> GetCanRecycleList(int userID)
        {
            IEnumerable<FlowTaskInfo> list = _task.GetCanRecycleList(userID);
            BindFormInfo(list);
            list = list.Where(t => t.FormInfo.State < (int)FormState.已结束);//只有绑定后才能过滤
            return list;
        }
       
        /// <summary>
        /// 删除草稿箱的内容
        /// </summary>
        /// <param name="taskIDs"></param>
        public void DeleteDraft(List<string> taskIDs)
        {
            _task.DeleteDraft(taskIDs);
        }

        /// <summary>
        /// 对于列表绑上表单信息
        /// </summary>
        /// <param name="tasks"></param>
        private void BindFormInfo(IEnumerable<FlowTaskInfo> tasks)
        {
            IEnumerable<int> formIDs = (from t in tasks
                                        select t.FormID).Distinct<int>();

            List<FlowFormInfo> forms = _form.GetList(formIDs);

            foreach (FlowTaskInfo task in tasks)
            {
                task.FormInfo = forms.Where(f => f.ID == task.FormID).First();
            }

        }

        /// <summary>
        /// 回收一个任务，用于错发回收
        /// </summary>
        /// <param name="id"></param>
        /// <returns>是否回收成功</returns>
        public bool Recycle(object taskID)
        {
            if (CanBeRecycled(taskID))
            {
                //为了防止在回收前被并发的审批，如果下一节点被审批，也应该把下一任务全删除
                _task.Recycle(taskID,true);


                //如果此任务节点是并发结点，关系是逻辑与，则要把并发任务的产生的任务删除，如果是逻辑或则没关系
                FlowTaskInfo info = this.GetInfo(taskID);
                if (info.ReceiveNodeInfo.IsParallel && info.ReceiveNodeInfo.ParallelMode == (int)ParallelMode.逻辑与)
                {
                    foreach (FlowTaskInfo task in info.PreTaskInfo.NextTaskInfos)
                    {
                        if (task.ID.ToString() != taskID.ToString())
                        {
                            _task.Recycle(task.ID, false);
                        }
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
            
        }

        /// <summary>
        /// 判断该任务能否被回收
        /// </summary>
        /// <param name="taskID"></param>
        /// <returns></returns>
        private bool CanBeRecycled(object taskID)
        {
            //判断条件如下：
            //1、是该任务的子任务
            //2、如有有子任务(包括加签和传阅，状态是待处理（如果是会签节点，可能没有子任务）
            //3、该表单的状态是没有结束的.

            FlowTaskInfo info = this.GetInfo(taskID);

            bool flag = true;
            if (info.FormInfo.State >= (int)FormState.已结束)
            {
                flag = false;
            }
            else
            {
                int state = info.NextTaskInfos.Sum(t => t.State);
                flag = (state == 0) ? true : false;
            }

            return flag;
        }

        /// <summary>
        /// 获取已经审批的任务
        /// </summary>
        /// <param name="taskID"></param>
        /// <returns></returns>
        public List<FlowTaskInfo> GetApprovedTask(string taskID)
        {
            List<FlowTaskInfo> nodes = _task.GetApprovedTask(taskID);
            return nodes;
        }

        public int GetNodeID(int taskID)
        {
            return _task.GetNodeID(taskID);
        }
    }
}
